home *** CD-ROM | disk | FTP | other *** search
/ InterCD 2000 September / september_2000.iso / intercd / root / ^Linux / cdrecord-1.8.1 / cdrecord / modes.c < prev    next >
Encoding:
C/C++ Source or Header  |  1999-10-17  |  6.4 KB  |  245 lines

  1. /* @(#)modes.c    1.13 99/06/06 Copyright 1988 J. Schilling */
  2. #ifndef lint
  3. static    char sccsid[] =
  4.     "@(#)modes.c    1.13 99/06/06 Copyright 1988 J. Schilling";
  5. #endif
  6. /*
  7.  *    SCSI mode page handling
  8.  *
  9.  *    Copyright (c) 1988 J. Schilling
  10.  */
  11. /*
  12.  * This program is free software; you can redistribute it and/or modify
  13.  * it under the terms of the GNU General Public License as published by
  14.  * the Free Software Foundation; either version 2, or (at your option)
  15.  * any later version.
  16.  *
  17.  * This program is distributed in the hope that it will be useful,
  18.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  19.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  20.  * GNU General Public License for more details.
  21.  *
  22.  * You should have received a copy of the GNU General Public License
  23.  * along with this program; see the file COPYING.  If not, write to
  24.  * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  25.  */
  26.  
  27. #include <mconfig.h>
  28. #include <sys/types.h>
  29. #include <standard.h>
  30. #include <scg/scgcmd.h>
  31. #include <scg/scsireg.h>
  32. #include <scg/scsitransp.h>
  33.  
  34. #include "cdrecord.h"
  35.  
  36. EXPORT int    scsi_compliant;
  37.  
  38. LOCAL    BOOL    has_mode_page    __PR((SCSI *scgp, int page, char *pagename, int *lenp));
  39. EXPORT    BOOL    get_mode_params    __PR((SCSI *scgp, int page, char *pagename,
  40.                     u_char *modep, u_char *cmodep,
  41.                     u_char *dmodep, u_char *smodep,
  42.                     int *lenp));
  43. EXPORT    BOOL    set_mode_params    __PR((SCSI *scgp, char *pagename, u_char *modep,
  44.                     int len, int save, int secsize));
  45.  
  46. #define    XXX
  47.  
  48. #ifdef    XXX
  49. LOCAL
  50. BOOL has_mode_page(scgp, page, pagename, lenp)
  51.     SCSI    *scgp;
  52.     int    page;
  53.     char    *pagename;
  54.     int    *lenp;
  55. {
  56.     u_char    mode[0x100];
  57.     int    hdlen;
  58.     int    len = 1;                /* Nach SCSI Norm */
  59.     int    try = 0;
  60.     struct    scsi_mode_page_header *mp;
  61.  
  62. again:
  63.     fillbytes((caddr_t)mode, sizeof(mode), '\0');
  64.     if (lenp)
  65.         *lenp = 0;
  66.  
  67.     (void)test_unit_ready(scgp);
  68.     scgp->silent++;
  69. /* Maxoptix bringt Aborted cmd 0x0B mit code 0x4E (overlapping cmds)*/
  70.  
  71.     /*
  72.      * The Matsushita CW-7502 will sometimes deliver a zeroed
  73.      * mode page 2A if "Page n default" is used instead of "current".
  74.      */
  75.     if (mode_sense(scgp, mode, len, page, 0) < 0) {    /* Page n current */
  76.         scgp->silent--;
  77.         return (FALSE);
  78.     } else {
  79.         len = ((struct scsi_mode_header *)mode)->sense_data_len + 1;
  80.     }
  81.     if (mode_sense(scgp, mode, len, page, 0) < 0) {    /* Page n current */
  82.         scgp->silent--;
  83.         return (FALSE);
  84.     }
  85.     scgp->silent--;
  86.  
  87.     if (scgp->verbose)
  88.         scsiprbytes("Mode Sense Data", mode, len - scsigetresid(scgp));
  89.     hdlen = sizeof(struct scsi_mode_header) +
  90.             ((struct scsi_mode_header *)mode)->blockdesc_len;
  91.     mp = (struct scsi_mode_page_header *)(mode + hdlen);
  92.     if (scgp->verbose)
  93.         scsiprbytes("Mode Page  Data", (u_char *)mp, mp->p_len+2);
  94.  
  95.     if (mp->p_len == 0) {
  96.         if (!scsi_compliant && try == 0) {
  97.             len = hdlen;
  98.             /*
  99.              * add sizeof page header (page # + len byte)
  100.              * (should normaly result in len == 14)
  101.              * this allowes to work with:
  102.              *     Quantum Q210S    (wants at least 13)
  103.              *     MD2x        (wants at least 4)
  104.              */
  105.             len += 2;
  106.             try++;
  107.             goto again;
  108.         }
  109.         /* XXX if (!nowarn) */
  110.         errmsgno(EX_BAD,
  111.             "Warning: controller returns zero sized %s page.\n",
  112.                                 pagename);
  113.     }
  114.     if (!scsi_compliant &&
  115.         (len < (int)(mp->p_len + hdlen + 2))) {
  116.         len = mp->p_len + hdlen + 2;
  117.  
  118.         /* XXX if (!nowarn) */
  119.         errmsgno(EX_BAD,
  120.             "Warning: controller returns wrong size for %s page.\n",
  121.                                 pagename);
  122.     }
  123.     if (mp->p_code != page) {
  124.         /* XXX if (!nowarn) */
  125.         errmsgno(EX_BAD,
  126.             "Warning: controller returns wrong page %X for %s page (%X).\n",
  127.                         mp->p_code, pagename, page);
  128.         return (FALSE);
  129.     }
  130.  
  131.     if (lenp)
  132.         *lenp = len;
  133.     return (mp->p_len > 0);
  134. }
  135. #endif
  136.  
  137. EXPORT
  138. BOOL get_mode_params(scgp, page, pagename, modep, cmodep, dmodep, smodep, lenp)
  139.     SCSI    *scgp;
  140.     int    page;
  141.     char    *pagename;
  142.     u_char    *modep;
  143.     u_char    *cmodep;
  144.     u_char    *dmodep;
  145.     u_char    *smodep;
  146.     int    *lenp;
  147. {
  148.     int    len;
  149.     BOOL    ret = TRUE;
  150.  
  151. #ifdef    XXX
  152.     if (lenp)
  153.         *lenp = 0;
  154.     if (!has_mode_page(scgp, page, pagename, &len)) {
  155.         if (!scgp->silent) errmsgno(EX_BAD,
  156.             "Warning: controller does not support %s page.\n",
  157.                                 pagename);
  158.         return (FALSE);
  159.     }
  160.     if (lenp)
  161.         *lenp = len;
  162. #else
  163.     if (lenp == 0)
  164.         len = 0xFF;
  165. #endif
  166.  
  167.     if (modep) {
  168.         fillbytes(modep, 0x100, '\0');
  169.         if (mode_sense(scgp, modep, len, page, 0) < 0) {/* Page x current */
  170.             errmsgno(EX_BAD, "Cannot get %s data.\n", pagename);
  171.             ret = FALSE;
  172.         } else if (scgp->verbose) {
  173.             scsiprbytes("Mode Sense Data", modep, len - scsigetresid(scgp));
  174.         }
  175.     }
  176.  
  177.     if (cmodep) {
  178.         fillbytes(cmodep, 0x100, '\0');
  179.         if (mode_sense(scgp, cmodep, len, page, 1) < 0) {/* Page x change */
  180.             errmsgno(EX_BAD, "Cannot get %s mask.\n", pagename);
  181.             ret = FALSE;
  182.         } else if (scgp->verbose) {
  183.             scsiprbytes("Mode Sense Data", cmodep, len - scsigetresid(scgp));
  184.         }
  185.     }
  186.  
  187.     if (dmodep) {
  188.         fillbytes(dmodep, 0x100, '\0');
  189.         if (mode_sense(scgp, dmodep, len, page, 2) < 0) {/* Page x default */
  190.             errmsgno(EX_BAD, "Cannot get default %s data.\n",
  191.                                 pagename);
  192.             ret = FALSE;
  193.         } else if (scgp->verbose) {
  194.             scsiprbytes("Mode Sense Data", dmodep, len - scsigetresid(scgp));
  195.         }
  196.     }
  197.  
  198.     if (smodep) {
  199.         fillbytes(smodep, 0x100, '\0');
  200.         if (mode_sense(scgp, smodep, len, page, 3) < 0) {/* Page x saved */
  201.             errmsgno(EX_BAD, "Cannot get saved %s data.\n", pagename);
  202.             ret = FALSE;
  203.         } else if (scgp->verbose) {
  204.             scsiprbytes("Mode Sense Data", smodep, len - scsigetresid(scgp));
  205.         }
  206.     }
  207.  
  208.     return (ret);
  209. }
  210.  
  211. EXPORT
  212. BOOL set_mode_params(scgp, pagename, modep, len, save, secsize)
  213.     SCSI    *scgp;
  214.     char    *pagename;
  215.     u_char    *modep;
  216.     int    len;
  217.     int    save;
  218.     int    secsize;
  219. {
  220.     int    i;
  221.  
  222.     ((struct scsi_modesel_header *)modep)->sense_data_len    = 0;
  223.     ((struct scsi_modesel_header *)modep)->res2        = 0;
  224.  
  225.     i = ((struct scsi_mode_header *)modep)->blockdesc_len;
  226.     if (i > 0) {
  227.         i_to_3_byte(
  228.             ((struct scsi_mode_data *)modep)->blockdesc.nlblock,
  229.                                 0);
  230.         if (secsize >= 0)
  231.         i_to_3_byte(((struct scsi_mode_data *)modep)->blockdesc.lblen,
  232.                             secsize);
  233.     }
  234.  
  235.     if (save == 0 || mode_select(scgp, modep, len, save, scgp->inq->data_format >= 2) < 0) {
  236.         if (mode_select(scgp, modep, len, 0, scgp->inq->data_format >= 2) < 0) {
  237.             errmsgno(EX_BAD,
  238.                "Warning: using default %s data.\n", pagename);
  239.             scsiprbytes("Mode Select Data", modep, len);
  240.             return (FALSE);
  241.         }
  242.     }
  243.     return (TRUE);
  244. }
  245.